Micron Document
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| SparkN0de-git | SparkN0de |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


Displaying Raw • Download


Console.h 4564dc3e9e5bf1072fdec4ae7482520e7cdf0e09 (4564dc3e) Text, 5.28 KB

T8b949e// Copyright (C) 2024, Mark Qvist

T8b949e// This program is free software: you can redistribute it and/or modify
T8b949e// it under the terms of the GNU General Public License as published by
T8b949e// the Free Software Foundation, either version 3 of the License, or
T8b949e// (at your option) any later version.

T8b949e// This program is distributed in the hope that it will be useful,
T8b949e// but WITHOUT ANY WARRANTY; without even the implied warranty of
T8b949e// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
T8b949e// GNU General Public License for more details.

T8b949e// You should have received a copy of the GNU General Public License
T8b949e// along with this program. If not, see <https://www.gnu.org/licenses/>.

Tff7b72#Tff7b72include T8b949e<FS.h>
Tff7b72#Tff7b72include T8b949e<SPIFFS.h>
Tff7b72#Tff7b72include T8b949e<WiFi.h>
Tff7b72#Tff7b72include T8b949e<WebServer.h>

Tff7b72#Tff7b72include T8b949e"SD.h"
Tff7b72#Tff7b72include T8b949e"SPI.h"
Tff7b72#Tff7b72if HAS_SD
Te6edf3SPIClass Tff7b72*Te6edf3spi Tff7b72= Tffa657NULLTb4b4b4;
Tff7b72#Tff7b72endif


Tff7b72#Tff7b72if CONFIG_IDF_TARGET_ESP32
Tff7b72#Tff7b72include T8b949e"esp32/rom/rtc.h"
Tff7b72#Tff7b72elif CONFIG_IDF_TARGET_ESP32S2
Tff7b72#Tff7b72include T8b949e"esp32s2/rom/rtc.h"
Tff7b72#Tff7b72elif CONFIG_IDF_TARGET_ESP32C3
Tff7b72#Tff7b72include T8b949e"esp32c3/rom/rtc.h"
Tff7b72#Tff7b72elif CONFIG_IDF_TARGET_ESP32S3
Tff7b72#Tff7b72include T8b949e"esp32s3/rom/rtc.h"
Tff7b72#Tff7b72else
Tff7b72#Tff7b72error Target CONFIG_IDF_TARGET is not supported
Tff7b72#Tff7b72endif

Te6edf3WebServer Td2a8ffserverTb4b4b4(T79c0ff80Tb4b4b4)Tb4b4b4;

Tffa657void Td2a8ffconsole_dbgTb4b4b4(Te6edf3String Te6edf3msgTb4b4b4) Tb4b4b4{
Te6edf3SerialTb4b4b4.Te6edf3printTb4b4b4(Ta5d6ff"Ta5d6ff[Webserver] Ta5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3SerialTb4b4b4.Te6edf3printlnTb4b4b4(Te6edf3msgTb4b4b4)Tb4b4b4;
Tb4b4b4}

Tffa657bool Td2a8ffexistsTb4b4b4(Te6edf3String Te6edf3pathTb4b4b4)Tb4b4b4{
Tffa657bool Te6edf3yes Tff7b72= Tffa657falseTb4b4b4;
Te6edf3File Te6edf3file Tff7b72= Te6edf3SPIFFSTb4b4b4.Te6edf3openTb4b4b4(Te6edf3pathTb4b4b4, Ta5d6ff"Ta5d6ffrTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72ifTb4b4b4(Tff7b72!Te6edf3fileTb4b4b4.Te6edf3isDirectoryTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4{
Te6edf3yes Tff7b72= Tffa657trueTb4b4b4;
Tb4b4b4}
Te6edf3fileTb4b4b4.Te6edf3closeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72return Te6edf3yesTb4b4b4;
Tb4b4b4}

Te6edf3String Td2a8ffconsole_get_content_typeTb4b4b4(Te6edf3String Te6edf3filenameTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3serverTb4b4b4.Te6edf3hasArgTb4b4b4(Ta5d6ff"Ta5d6ffdownloadTa5d6ff"Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72return Ta5d6ff"Ta5d6ffapplication/octet-streamTa5d6ff"Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3filenameTb4b4b4.Te6edf3endsWithTb4b4b4(Ta5d6ff"Ta5d6ff.htmTa5d6ff"Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72return Ta5d6ff"Ta5d6fftext/htmlTa5d6ff"Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3filenameTb4b4b4.Te6edf3endsWithTb4b4b4(Ta5d6ff"Ta5d6ff.htmlTa5d6ff"Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72return Ta5d6ff"Ta5d6fftext/htmlTa5d6ff"Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3filenameTb4b4b4.Te6edf3endsWithTb4b4b4(Ta5d6ff"Ta5d6ff.cssTa5d6ff"Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72return Ta5d6ff"Ta5d6fftext/cssTa5d6ff"Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3filenameTb4b4b4.Te6edf3endsWithTb4b4b4(Ta5d6ff"Ta5d6ff.jsTa5d6ff"Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72return Ta5d6ff"Ta5d6ffapplication/javascriptTa5d6ff"Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3filenameTb4b4b4.Te6edf3endsWithTb4b4b4(Ta5d6ff"Ta5d6ff.pngTa5d6ff"Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72return Ta5d6ff"Ta5d6ffimage/pngTa5d6ff"Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3filenameTb4b4b4.Te6edf3endsWithTb4b4b4(Ta5d6ff"Ta5d6ff.gifTa5d6ff"Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72return Ta5d6ff"Ta5d6ffimage/gifTa5d6ff"Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3filenameTb4b4b4.Te6edf3endsWithTb4b4b4(Ta5d6ff"Ta5d6ff.jpgTa5d6ff"Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72return Ta5d6ff"Ta5d6ffimage/jpegTa5d6ff"Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3filenameTb4b4b4.Te6edf3endsWithTb4b4b4(Ta5d6ff"Ta5d6ff.icoTa5d6ff"Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72return Ta5d6ff"Ta5d6ffimage/x-iconTa5d6ff"Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3filenameTb4b4b4.Te6edf3endsWithTb4b4b4(Ta5d6ff"Ta5d6ff.xmlTa5d6ff"Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72return Ta5d6ff"Ta5d6fftext/xmlTa5d6ff"Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3filenameTb4b4b4.Te6edf3endsWithTb4b4b4(Ta5d6ff"Ta5d6ff.pdfTa5d6ff"Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72return Ta5d6ff"Ta5d6ffapplication/x-pdfTa5d6ff"Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3filenameTb4b4b4.Te6edf3endsWithTb4b4b4(Ta5d6ff"Ta5d6ff.zipTa5d6ff"Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72return Ta5d6ff"Ta5d6ffapplication/x-zipTa5d6ff"Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3filenameTb4b4b4.Te6edf3endsWithTb4b4b4(Ta5d6ff"Ta5d6ff.gzTa5d6ff"Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72return Ta5d6ff"Ta5d6ffapplication/x-gzipTa5d6ff"Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3filenameTb4b4b4.Te6edf3endsWithTb4b4b4(Ta5d6ff"Ta5d6ff.whlTa5d6ff"Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72return Ta5d6ff"Ta5d6ffapplication/octet-streamTa5d6ff"Tb4b4b4;
Tb4b4b4}
Tff7b72return Ta5d6ff"Ta5d6fftext/plainTa5d6ff"Tb4b4b4;
Tb4b4b4}

Tffa657bool Td2a8ffconsole_serve_fileTb4b4b4(Te6edf3String Te6edf3pathTb4b4b4) Tb4b4b4{
Te6edf3console_dbgTb4b4b4(Ta5d6ff"Ta5d6ffRequest for: Ta5d6ff"Tff7b72+Te6edf3pathTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3pathTb4b4b4.Te6edf3endsWithTb4b4b4(Ta5d6ff"Ta5d6ff/Ta5d6ff"Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3path Tff7b72+Tff7b72= Ta5d6ff"Ta5d6ffindex.htmlTa5d6ff"Tb4b4b4;
Tb4b4b4}

Tff7b72if Tb4b4b4(Te6edf3path Tff7b72=Tff7b72= Ta5d6ff"Ta5d6ff/r/manual/index.htmlTa5d6ff"Tb4b4b4) Tb4b4b4{
Te6edf3path Tff7b72= Ta5d6ff"Ta5d6ff/m.htmlTa5d6ff"Tb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3path Tff7b72=Tff7b72= Ta5d6ff"Ta5d6ff/r/manual/Reticulum Manual.pdfTa5d6ff"Tb4b4b4) Tb4b4b4{
Te6edf3path Tff7b72= Ta5d6ff"Ta5d6ff/h.htmlTa5d6ff"Tb4b4b4;
Tb4b4b4}


Te6edf3String Te6edf3content_type Tff7b72= Te6edf3console_get_content_typeTb4b4b4(Te6edf3pathTb4b4b4)Tb4b4b4;
Te6edf3String Te6edf3pathWithGz Tff7b72= Te6edf3path Tff7b72+ Ta5d6ff"Ta5d6ff.gzTa5d6ff"Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3existsTb4b4b4(Te6edf3pathWithGzTb4b4b4) Tff7b72|Tff7b72| Te6edf3existsTb4b4b4(Te6edf3pathTb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3existsTb4b4b4(Te6edf3pathWithGzTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3path Tff7b72+Tff7b72= Ta5d6ff"Ta5d6ff.gzTa5d6ff"Tb4b4b4;
Tb4b4b4}
Te6edf3File Te6edf3file Tff7b72= Te6edf3SPIFFSTb4b4b4.Te6edf3openTb4b4b4(Te6edf3pathTb4b4b4, Ta5d6ff"Ta5d6ffrTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3console_dbgTb4b4b4(Ta5d6ff"Ta5d6ffServing file to clientTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3serverTb4b4b4.Te6edf3streamFileTb4b4b4(Te6edf3fileTb4b4b4, Te6edf3content_typeTb4b4b4)Tb4b4b4;
Te6edf3fileTb4b4b4.Te6edf3closeTb4b4b4(Tb4b4b4)Tb4b4b4;

Te6edf3console_dbgTb4b4b4(Ta5d6ff"Ta5d6ffFile serving doneTffea00\nTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72return Tffa657trueTb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Tffa657int Te6edf3spos Tff7b72= Te6edf3pathWithGzTb4b4b4.Te6edf3lastIndexOfTb4b4b4(Ta5d6ff'Ta5d6ff/Ta5d6ff'Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3spos Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3String Te6edf3remap_path Tff7b72= Ta5d6ff"Ta5d6ff/dTa5d6ff"Tb4b4b4;
Te6edf3remap_pathTb4b4b4.Te6edf3concatTb4b4b4(Te6edf3pathWithGzTb4b4b4.Te6edf3substringTb4b4b4(Te6edf3sposTb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3SerialTb4b4b4.Te6edf3printlnTb4b4b4(Te6edf3remap_pathTb4b4b4)Tb4b4b4;

Tff7b72if Tb4b4b4(Te6edf3existsTb4b4b4(Te6edf3remap_pathTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3File Te6edf3file Tff7b72= Te6edf3SPIFFSTb4b4b4.Te6edf3openTb4b4b4(Te6edf3remap_pathTb4b4b4, Ta5d6ff"Ta5d6ffrTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3console_dbgTb4b4b4(Ta5d6ff"Ta5d6ffServing remapped file to clientTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3serverTb4b4b4.Te6edf3streamFileTb4b4b4(Te6edf3fileTb4b4b4, Te6edf3content_typeTb4b4b4)Tb4b4b4;
Te6edf3console_dbgTb4b4b4(Ta5d6ff"Ta5d6ffClosing fileTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3fileTb4b4b4.Te6edf3closeTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3console_dbgTb4b4b4(Ta5d6ff"Ta5d6ffFile serving doneTffea00\nTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72return Tffa657trueTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}

Te6edf3console_dbgTb4b4b4(Ta5d6ff"Ta5d6ffError: Could not open file for servingTffea00\nTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}

Tffa657void Td2a8ffconsole_register_pagesTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3serverTb4b4b4.Te6edf3onNotFoundTb4b4b4(Tb4b4b4[Tb4b4b4]Tb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3console_serve_fileTb4b4b4(Te6edf3serverTb4b4b4.Te6edf3uriTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3serverTb4b4b4.Te6edf3sendTb4b4b4(T79c0ff404Tb4b4b4, Ta5d6ff"Ta5d6fftext/plainTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffNot FoundTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4}

Tffa657void Td2a8ffconsole_startTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3SerialTb4b4b4.Te6edf3printlnTb4b4b4(Ta5d6ff"Ta5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3console_dbgTb4b4b4(Ta5d6ff"Ta5d6ffStarting Access Point...Ta5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3WiFiTb4b4b4.Te6edf3softAPTb4b4b4(Te6edf3bt_devnameTb4b4b4)Tb4b4b4;
Te6edf3delayTb4b4b4(T79c0ff150Tb4b4b4)Tb4b4b4;
Te6edf3IPAddress Te6edf3ipTb4b4b4(T79c0ff10Tb4b4b4, T79c0ff0Tb4b4b4, T79c0ff0Tb4b4b4, T79c0ff1Tb4b4b4)Tb4b4b4;
Te6edf3IPAddress Te6edf3nmTb4b4b4(T79c0ff255Tb4b4b4, T79c0ff255Tb4b4b4, T79c0ff255Tb4b4b4, T79c0ff0Tb4b4b4)Tb4b4b4;
Te6edf3WiFiTb4b4b4.Te6edf3softAPConfigTb4b4b4(Te6edf3ipTb4b4b4, Te6edf3ipTb4b4b4, Te6edf3nmTb4b4b4)Tb4b4b4;

Tff7b72ifTb4b4b4(Tff7b72!Te6edf3SPIFFSTb4b4b4.Te6edf3beginTb4b4b4(Tffa657trueTb4b4b4)Tb4b4b4)Tb4b4b4{
Te6edf3console_dbgTb4b4b4(Ta5d6ff"Ta5d6ffError: Could not mount SPIFFSTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72returnTb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3console_dbgTb4b4b4(Ta5d6ff"Ta5d6ffSPIFFS ReadyTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}

Tff7b72#Tff7b72if HAS_SD
Te6edf3spi Tff7b72= Te6edf3new Te6edf3SPIClassTb4b4b4(Te6edf3HSPITb4b4b4)Tb4b4b4;
Te6edf3spiTff7b72-Tff7b72>Te6edf3beginTb4b4b4(Te6edf3SD_CLKTb4b4b4, Te6edf3SD_MISOTb4b4b4, Te6edf3SD_MOSITb4b4b4, Te6edf3SD_CSTb4b4b4)Tb4b4b4;
Tff7b72ifTb4b4b4(Tff7b72!Te6edf3SDTb4b4b4.Te6edf3beginTb4b4b4(Te6edf3SD_CSTb4b4b4, Tff7b72*Te6edf3spiTb4b4b4)Tb4b4b4)Tb4b4b4{
Te6edf3console_dbgTb4b4b4(Ta5d6ff"Ta5d6ffNo SD card insertedTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Tffa657uint8_t Te6edf3cardType Tff7b72= Te6edf3SDTb4b4b4.Te6edf3cardTypeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72ifTb4b4b4(Te6edf3cardType Tff7b72=Tff7b72= Te6edf3CARD_NONETb4b4b4)Tb4b4b4{
Te6edf3console_dbgTb4b4b4(Ta5d6ff"Ta5d6ffNo SD card typeTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3console_dbgTb4b4b4(Ta5d6ff"Ta5d6ffSD Card Type: Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72ifTb4b4b4(Te6edf3cardType Tff7b72=Tff7b72= Te6edf3CARD_MMCTb4b4b4)Tb4b4b4{
Te6edf3console_dbgTb4b4b4(Ta5d6ff"Ta5d6ffMMCTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72ifTb4b4b4(Te6edf3cardType Tff7b72=Tff7b72= Te6edf3CARD_SDTb4b4b4)Tb4b4b4{
Te6edf3console_dbgTb4b4b4(Ta5d6ff"Ta5d6ffSDSCTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72ifTb4b4b4(Te6edf3cardType Tff7b72=Tff7b72= Te6edf3CARD_SDHCTb4b4b4)Tb4b4b4{
Te6edf3console_dbgTb4b4b4(Ta5d6ff"Ta5d6ffSDHCTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3console_dbgTb4b4b4(Ta5d6ff"Ta5d6ffUNKNOWNTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tffa657uint64_t Te6edf3cardSize Tff7b72= Te6edf3SDTb4b4b4.Te6edf3cardSizeTb4b4b4(Tb4b4b4) Tff7b72/ Tb4b4b4(T79c0ff1024 Tff7b72* T79c0ff1024Tb4b4b4)Tb4b4b4;
Te6edf3SerialTb4b4b4.Te6edf3printfTb4b4b4(Ta5d6ff"Ta5d6ffSD Card Size: %lluMBTffea00\nTa5d6ff"Tb4b4b4, Te6edf3cardSizeTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72#Tff7b72endif

Te6edf3console_register_pagesTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3serverTb4b4b4.Te6edf3beginTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3led_indicate_consoleTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}

Tffa657void Td2a8ffconsole_loopTb4b4b4(Tb4b4b4)Tb4b4b4{
Te6edf3serverTb4b4b4.Te6edf3handleClientTb4b4b4(Tb4b4b4)Tb4b4b4;
T8b949e// Internally, this yields the thread and allows
T8b949e// other tasks to run.
Te6edf3delayTb4b4b4(T79c0ff2Tb4b4b4)Tb4b4b4;
Tb4b4b4}


──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────